home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / UTILITY1 / MSWSRC35.ZIP / XFILEWND.CPP < prev    next >
C/C++ Source or Header  |  1993-09-07  |  10KB  |  383 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. /* --------------------------------------------------------
  4.   FILEWND.CPP
  5.   Defines type TxFileWindow, a text editor which can read
  6.   and write to a file.
  7.   -------------------------------------------------------- */
  8.  
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <alloc.h>
  12. #include "xfilewnd.h"
  13.  
  14. #define Min(a, b)     ((a) < (b) ? (a) : (b))
  15.  
  16. /* Constructor for a TxFileWindow.  Initializes its data members using
  17.   passed parameters and default values. */
  18. TxFileWindow::TxFileWindow(PTWindowsObject AParent,LPSTR ATitle,
  19.                          LPSTR AFileName, PTModule AModule)
  20.              :   TEditWindow(AParent, ATitle, AModule)
  21. {
  22.   IsNewFile = TRUE;
  23.   FileName = _fstrdup(AFileName ? AFileName : "");
  24. }
  25.  
  26. /* Dispose of the file name. */
  27. TxFileWindow::~TxFileWindow()
  28. {
  29.   if ( FileName )
  30.     farfree(FileName);
  31. }
  32.  
  33. /* Performs setup for a TxFileWindow, appending 'Untitled' to its caption */
  34. void TxFileWindow::SetupWindow()
  35. {
  36.   TEditWindow::SetupWindow();
  37.   SetFileName(FileName);
  38.   if ( FileName[0] != '\0')
  39.     if ( !Read() )
  40.       SetFileName("");
  41. }
  42.  
  43. /* Sets the file name of the window and updates the caption. */
  44. void TxFileWindow::SetFileName(LPSTR AFileName)
  45. {
  46.   char NewCaption[81];
  47.   LPSTR P[2];
  48.  
  49.   if ( FileName != AFileName )
  50.   {
  51.     farfree(FileName);
  52.     FileName = _fstrdup(AFileName ? AFileName : "");
  53.   }
  54.   P[0] = Title;
  55.   if ( FileName[0] == '\0' )
  56.     P[1] = "(Untitled)";
  57.   else
  58.     P[1] = AFileName;
  59.   if ( Title == NULL || Title[0] == '\0' )
  60.     SetWindowText(HWindow, P[1]);
  61.   else
  62.   {
  63.     wvsprintf(NewCaption, "%s - %s", (LPSTR)P);
  64.     SetWindowText(HWindow, NewCaption);
  65.   }
  66. }
  67.  
  68. /* Begins the edit of a new file, after determining that it is Ok to
  69.   clear the TEdit's text. */
  70. void TxFileWindow::NewFile()
  71. {
  72.   if ( CanClear() )
  73.   {
  74.     Editor->Clear();
  75.     InvalidateRect(Editor->HWindow, NULL, FALSE);
  76.     Editor->ClearModify();
  77.     IsNewFile = TRUE;
  78.     SetFileName(NULL);
  79.   }
  80. }
  81.  
  82. /* Replaces the current file with the given file. */
  83. void TxFileWindow::ReplaceWith(LPSTR AFileName)
  84. {
  85.   char OldName[MAXPATH];
  86.  
  87.   _fstrcpy(OldName, FileName);
  88.   SetFileName(AFileName);
  89.   if ( Read() )
  90.     InvalidateRect(Editor->HWindow, NULL, FALSE);
  91.   else
  92.     SetFileName(OldName);
  93. }
  94.  
  95. /* Brings up a dialog allowing the user to open a file into this
  96.   window.  Same as selecting File|Open from the menus. */
  97. void TxFileWindow::Open()
  98. {
  99.   char TmpName[MAXPATH];
  100.  
  101.   if ( CanClear() && (GetModule()->ExecDialog(
  102.          new TFileDialog(this, SD_FILEOPEN,
  103.                          _fstrcpy(TmpName, "*.*"), GetModule())) == IDOK) )
  104.     ReplaceWith(TmpName);
  105. }
  106.  
  107. static HANDLE LocalReAllocDS(HANDLE hMem, WORD wBytes, WORD wFlags,
  108.                                                                  WORD TheDS)
  109. {
  110.   WORD SavedDS;
  111.   HANDLE ReturnValue;
  112.  
  113.   SavedDS = _DS;
  114.   _DS = TheDS;
  115.   ReturnValue = LocalReAlloc(hMem, wBytes, wFlags);
  116.   _DS = SavedDS;
  117.   return ReturnValue;
  118. }
  119.  
  120. static LPSTR LocalLockDS(HANDLE hMem, WORD TheDS)
  121. {
  122.   WORD SavedDS;
  123.   LPSTR ReturnValue;
  124.  
  125.   SavedDS = _DS;
  126.   _DS = TheDS;
  127.   ReturnValue = (LPSTR)LocalLock(hMem);
  128.   _DS = SavedDS;
  129.   return ReturnValue;
  130. }
  131.  
  132. static BOOL LocalUnlockDS(HANDLE hMem, WORD TheDS)
  133. {
  134.   WORD SavedDS;
  135.   BOOL ReturnValue;
  136.  
  137.   SavedDS = _DS;
  138.   _DS = TheDS;
  139.   ReturnValue = LocalUnlock(hMem);
  140.   _DS = SavedDS;
  141.   return ReturnValue;
  142. }
  143.  
  144. /* Reads the contents of a previously-specified file into the TEdit
  145.   child control. */
  146. BOOL TxFileWindow::Read()
  147. {
  148.   long CharsToRead;
  149.   UINT HEditorBuffer;
  150.   LPSTR EditorBuffer;
  151.   WORD EditorsDS;
  152.   char S[MAXPATH + 33];
  153.   int AFile;
  154.   BOOL Success = FALSE;
  155.  
  156.   AFile = _lopen(FileName, OF_READ);
  157.   if ( AFile != -1 )
  158.   {
  159.     CharsToRead = _llseek(AFile, 0L, 2);
  160.     _llseek(AFile, 0L, 0);
  161.     if ( CharsToRead < MaxInt && CharsToRead > 0 )
  162.     {
  163.       Editor->Clear();
  164.  
  165.       // attempt to reallocate Editor's buffer to the size of the file
  166.       HEditorBuffer = SendMessage(Editor->HWindow, EM_GETHANDLE, 0, 0L);
  167.       EditorsDS = FP_SEG(GlobalLock((Editor->GetModule())->hInstance));
  168.       if ( LocalReAllocDS((HANDLE)HEditorBuffer, (WORD)(CharsToRead+1),
  169.                           LHND, EditorsDS) != NULL )
  170.       {
  171.         // read the file into EditorBuffer
  172.     EditorBuffer = (LPSTR)LocalLockDS((HANDLE)HEditorBuffer, EditorsDS);
  173.         if ( _lread(AFile, EditorBuffer, (WORD)CharsToRead) == CharsToRead )
  174.         {
  175.           // NULL terminate Editor's buffer
  176.           EditorBuffer[(WORD)CharsToRead] = '\0';
  177.       LocalUnlockDS((HANDLE)HEditorBuffer, EditorsDS);
  178.  
  179.       SendMessage(Editor->HWindow, EM_SETHANDLE, HEditorBuffer, 0L);
  180.           Success = TRUE;
  181.  
  182.           IsNewFile = FALSE;
  183.           Editor->ClearModify();
  184.           Editor->SetSelection(0,0);
  185.         }
  186.       }
  187.       GlobalUnlock((Editor->GetModule())->hInstance);
  188.     }
  189.     _lclose(AFile);
  190.   }
  191.   if ( !Success )
  192.   {
  193.     wsprintf(S, "Unable to read file \"%s\" from disk", FileName);
  194.     MessageBox(HWindow, S, GetModule()->Name, MB_ICONEXCLAMATION | MB_OK);
  195.   }
  196.   return Success;
  197. }
  198.  
  199. /* Saves the contents of the TEdit child control into the file currently
  200.   being editted.  Returns true if the file was saved or
  201.   Editor->IsModified returns FALSE (contents already saved). */
  202. BOOL TxFileWindow::Save()
  203. {
  204.   if ( Editor->IsModified() )
  205.   {
  206.     if ( IsNewFile )
  207.       return SaveAs();
  208.     else
  209.     {
  210.       if ( Write() )
  211.         return TRUE;
  212.       else
  213.         return FALSE;
  214.     }
  215.   }
  216.   else       // Editor's contents haven't been changed. No need to write.
  217.     return TRUE;
  218. }
  219.  
  220. /* Saves the contents of the TEdit child control into a file whose name
  221.   is retrieved from the user, through execution of a "Save" file
  222.   dialog. Returns true if the file was saved. */
  223. BOOL TxFileWindow::SaveAs()
  224. {
  225.   char TmpName[MAXPATH];
  226.   char OldName[MAXPATH];
  227.   OFSTRUCT TmpOfStruct;
  228.   char S[MAXPATH+20];
  229.  
  230.   _fstrcpy(OldName, FileName);
  231.   if ( FileName )
  232.     _fstrcpy(TmpName, FileName);
  233.   else
  234.     TmpName[0] = '\0';
  235.   if ( GetModule()->ExecDialog( new TFileDialog
  236.             (this, SD_FILESAVE, TmpName, GetModule())) == IDOK )
  237.   {
  238.     if ( OpenFile(TmpName, &TmpOfStruct, OF_EXIST) != -1 )
  239.     {
  240.       wsprintf(S, "Replace Current \"%s\"?", (LPSTR)TmpName);
  241.       if ( MessageBox(HWindow, S, "File Changed",
  242.                           MB_YESNO | MB_ICONQUESTION) == IDNO )
  243.       {
  244.         SetFileName(OldName);
  245.         return FALSE;
  246.       }
  247.     }
  248.     SetFileName(TmpName);
  249.     if ( Write() )
  250.       return TRUE;
  251.     else
  252.     {
  253.       SetFileName(OldName);
  254.       return FALSE;
  255.     }
  256.   }
  257.   return FALSE;
  258. }
  259.  
  260. /* Writes the contents of the TEdit child control to a
  261. previously-specified file. */
  262. BOOL TxFileWindow::Write()
  263.    {
  264.    int AFile;
  265.    HANDLE hEditBuffer;                       /* handle to editing buffer      */
  266.    LPSTR pEditBuffer;                        /* address of the edit buffer      */
  267.    char S[MAXPATH + 33];
  268.    WORD EditorsDS;
  269.    HANDLE hinst;
  270.    
  271.    AFile = _lcreat(FileName, 0);
  272.    if ( AFile == -1 )
  273.       {
  274.       wsprintf(S, "Unable to write file \"%s\" to disk", FileName);
  275.       MessageBox(HWindow, S, GetModule()->Name, MB_ICONEXCLAMATION | MB_OK);
  276.       return FALSE;
  277.       }
  278.    else
  279.       {
  280.       
  281.       hEditBuffer = (HANDLE)SendMessage(Editor->HWindow, EM_GETHANDLE, 0, 0L);
  282.       EditorsDS = FP_SEG(GlobalLock((Editor->GetModule())->hInstance));
  283.       pEditBuffer = (LPSTR)LocalLockDS(hEditBuffer, EditorsDS);
  284.       
  285.       if (_lwrite(AFile, pEditBuffer, strlen(pEditBuffer)) == (WORD)-1)
  286.          {
  287.          LocalUnlockDS(hEditBuffer, EditorsDS);
  288.          GlobalUnlock((Editor->GetModule())->hInstance);
  289.          _lclose(AFile);
  290.          return FALSE;
  291.          }
  292.       IsNewFile = FALSE;
  293.       Editor->ClearModify();
  294.       LocalUnlockDS(hEditBuffer, EditorsDS);
  295.       GlobalUnlock((Editor->GetModule())->hInstance);
  296.       _lclose(AFile);
  297.       }
  298.    
  299.    return TRUE;
  300.    }
  301.  
  302. /* Returns a BOOL value indicating whether or not it is Ok to clear
  303.   the TEdit's